package com.template.utils;

import java.util.*;

public class test {
    // 用户-帖子互动数据：用户名 -> (帖子ID -> 是否点赞)
    private static Map<String, Map<String, Integer>> userPostInteractions = new HashMap<>();

    // 帖子数据库：帖子ID -> 内容
    private static Map<String, String> postDatabase = new HashMap<>();

    public static void main(String[] args) {
        // 初始化测试数据
        initializeTestData();

        // 为用户生成并排序帖子列表
        String targetUser = "user1";
        List<PostScore> rankedPosts = rankAllPostsForUser(targetUser);

        // 展示结果
        System.out.println("为用户 " + targetUser + " 排序后的完整帖子列表：");
        for (PostScore postScore : rankedPosts) {
            System.out.println("帖子: " + postScore.postId +
                    " | 内容: " + postDatabase.get(postScore.postId) +
                    " | 兴趣评分: " + String.format("%.2f", postScore.score));
        }
    }

    // 初始化测试数据
    private static void initializeTestData() {
        // 初始化帖子库
        postDatabase.put("post001", "人工智能最新发展动态");
        postDatabase.put("post002", "Java编程技巧分享");
        postDatabase.put("post003", "周末户外徒步好去处");
        postDatabase.put("post004", "深度学习模型优化方法");
        postDatabase.put("post005", "Spring框架使用心得");
        postDatabase.put("post006", "机器学习实战案例分析");

        // 用户1的互动
        Map<String, Integer> user1Interactions = new HashMap<>();
        user1Interactions.put("post001", 1);  // 点赞
        user1Interactions.put("post004", 1);
        user1Interactions.put("post005", 1);
        userPostInteractions.put("user1", user1Interactions);

        // 用户2的互动
        Map<String, Integer> user2Interactions = new HashMap<>();
        user2Interactions.put("post001", 1);
        user2Interactions.put("post002", 1);
        user2Interactions.put("post006", 1);
        userPostInteractions.put("user2", user2Interactions);

        // 用户3的互动
        Map<String, Integer> user3Interactions = new HashMap<>();
        user3Interactions.put("post003", 1);
        user3Interactions.put("post004", 1);
        user3Interactions.put("post005", 1);
        userPostInteractions.put("user3", user3Interactions);

        // 用户4的互动
        Map<String, Integer> user4Interactions = new HashMap<>();
        user4Interactions.put("post002", 1);
        user4Interactions.put("post005", 1);
        user4Interactions.put("post006", 1);
        userPostInteractions.put("user4", user4Interactions);
    }

    // 为用户生成全量帖子排序
    public static List<PostScore> rankAllPostsForUser(String targetUser) {
        List<PostScore> allPosts = new ArrayList<>();

        // 获取目标用户的互动记录
        Map<String, Integer> targetInteractions = userPostInteractions.getOrDefault(targetUser, new HashMap<>());

        // 如果没有其他用户或没有任何互动，直接返回随机排序
        if (userPostInteractions.size() <= 1 || userPostInteractions.values().stream().allMatch(Map::isEmpty)) {
            for (String postId : postDatabase.keySet()) {
                allPosts.add(new PostScore(postId, Math.random()));  // 使用随机分数作为默认排序
            }
            return sortPosts(allPosts);
        }

        // 计算相似用户
        Map<String, Double> similarUsers = calculateUserSimilarities(targetUser);

        // 为每个帖子计算排名分数
        for (String postId : postDatabase.keySet()) {
            double score = calculatePostScore(targetUser, postId, similarUsers, targetInteractions);
            allPosts.add(new PostScore(postId, score));
        }

        return sortPosts(allPosts);
    }

    // 计算用户相似度
    private static Map<String, Double> calculateUserSimilarities(String targetUser) {
        Map<String, Double> similarities = new HashMap<>();

        for (String otherUser : userPostInteractions.keySet()) {
            if (!otherUser.equals(targetUser)) {
                // 计算Jaccard相似度
                Map<String, Integer> targetSet = userPostInteractions.get(targetUser);
                Map<String, Integer> otherSet = userPostInteractions.get(otherUser);

                Set<String> intersection = new HashSet<>(targetSet.keySet());
                intersection.retainAll(otherSet.keySet());

                double jaccardSimilarity = (double) intersection.size() /
                        (targetSet.size() + otherSet.size() - intersection.size());

                similarities.put(otherUser, jaccardSimilarity);
            }
        }

        return similarities;
    }

    // 计算单个帖子的排名分数
    private static double calculatePostScore(String targetUser, String postId, Map<String, Double> similarUsers, Map<String, Integer> targetInteractions) {
        double score = 0;
        double totalWeight = 0;

        // 如果用户已经点赞过该帖子，则给予最高分
        if (targetInteractions.containsKey(postId)) {
            return Double.MAX_VALUE;  // 确保已点赞的帖子排在最前面
        }

        // 否则基于相似用户的喜好计算分数
        for (Map.Entry<String, Double> entry : similarUsers.entrySet()) {
            String similarUser = entry.getKey();
            double weight = entry.getValue();

            // 只有当相似用户喜欢过该帖子时才计入计算
            Map<String, Integer> interactions = userPostInteractions.get(similarUser);
            if (interactions.containsKey(postId)) {
                score += weight * interactions.get(postId);  // 假设1表示喜欢
                totalWeight += weight;
            }
        }

        // 防止除以零
        if (totalWeight == 0) {
            return 0.5;  // 给予中间分数
        }

        return score / totalWeight;
    }

    // 排序帖子
    private static List<PostScore> sortPosts(List<PostScore> posts) {
        posts.sort(new PostComparator());
        return posts;
    }

    // 帖子与评分的数据结构
    static class PostScore {
        String postId;
        double score;

        public PostScore(String postId, double score) {
            this.postId = postId;
            this.score = score;
        }
    }

    // 帖子比较器（按分数降序排列）
    static class PostComparator implements Comparator<PostScore> {
        @Override
        public int compare(PostScore p1, PostScore p2) {
            // 已点赞的帖子（分数为Double.MAX_VALUE）排在最前
            if (p1.score == Double.MAX_VALUE && p2.score != Double.MAX_VALUE) {
                return -1;
            } else if (p1.score != Double.MAX_VALUE && p2.score == Double.MAX_VALUE) {
                return 1;
            }

            // 如果分数相同，则随机排序
            if (Math.abs(p1.score - p2.score) < 0.001) {
                return Double.compare(Math.random(), Math.random()) > 0 ? 1 : -1;
            }

            // 否则按分数从高到低排序
            return Double.compare(p2.score, p1.score);
        }
    }
}